package com.sort.animation;

import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;

public class BiNodePanel extends JPanel {

    private volatile List<BiNode> biNodes = new ArrayList<>();

    public BiNodePanel(List<BiNode> biNodes) {
        setLayout(null);
        this.biNodes = biNodes;
        for(BiNode biNode:biNodes){
            this.add(biNode);
        }
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        Graphics2D g2d =    (Graphics2D)g.create();
        g2d.setColor(Color.RED);
        g2d.setStroke(new BasicStroke(3));
        for(int i=0 ; i<biNodes.size();i++){

            int left = 2 * i + 1;
            int right = 2 * i + 2;
            if(left < biNodes.size()){
                drawLine(g2d,biNodes.get(i),biNodes.get(left));
            }
            if(right < biNodes.size()){
                drawLine(g2d,biNodes.get(i),biNodes.get(right));
            }
        }

        g2d.dispose();
    }



    private void drawLine(Graphics2D g2d,BiNode node1,BiNode node2){

        boolean swap =  BiNodeStatus.SWAP == node1.getNodeStatus() && BiNodeStatus.SWAP == node2.getNodeStatus();

        Color color = swap ? Color.BLUE : Color.RED;

        int centerX1 = node1.getX() + node1.getWidth()/2;
        int centerY1 = node1.getY() + node1.getHeight()/2;
        int centerX2 = node2.getX() + node2.getWidth()/2;
        int centerY2 = node2.getY() + node2.getHeight()/2;
        g2d.setColor(color);
        g2d.drawLine(centerX1,centerY1,centerX2,centerY2);
    }


    public void doHeapSort(){

        for (int i = biNodes.size() - 1; i > 0; i--) {
            for (int j = i; j > 0; j--) {
                int parentIndex = (j - 1) / 2;

                biNodes.get(j).setNodeStatus(BiNodeStatus.COMPARE);
                biNodes.get(parentIndex).setNodeStatus(BiNodeStatus.COMPARE);


                repaint();
                try {
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }

                biNodes.get(j).setNodeStatus(BiNodeStatus.NORMAL);
                biNodes.get(parentIndex).setNodeStatus(BiNodeStatus.NORMAL);
                repaint();

                try {
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }

                if(biNodes.get(j).getValue() > biNodes.get(parentIndex).getValue()){

                    biNodes.get(j).setNodeStatus(BiNodeStatus.COMPARE);
                    biNodes.get(parentIndex).setNodeStatus(BiNodeStatus.COMPARE);
                    repaint();
                    try {
                        Thread.sleep(300);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    swap(j,parentIndex);
                    repaint();
                    try {
                        Thread.sleep(300);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }

                    biNodes.get(j).setNodeStatus(BiNodeStatus.NORMAL);
                    biNodes.get(parentIndex).setNodeStatus(BiNodeStatus.NORMAL);
                    repaint();
                }
            }

            swap(0,i);
            repaint();
            try {
                Thread.sleep(300);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }

    }

    private void swap(int i, int j) {

        int valueI = biNodes.get(i).getValue();
        int valueJ = biNodes.get(j).getValue();

        biNodes.get(i).setValue(valueJ);
        biNodes.get(i).setNodeStatus(BiNodeStatus.SWAP);
        biNodes.get(j).setValue(valueI);
        biNodes.get(j).setNodeStatus(BiNodeStatus.SWAP);
    }





}
